//
//  WmcBaseTagView.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/16.
//

import Kingfisher
import UIKit
import YPBedrock

extension WmcBaseTagView {
    enum TagStyle: Int, CaseIterable {
        /// 勾边文字
        case textHookEdge = 1
        /// 标注
        case marked = 2
        /// 标签
        case tag = 3
        /// 背景色文字
        case textBackground = 4

        struct Info {
            var perviewImage: UIImage
        }

        var info: Info {
            switch self {
            case .textHookEdge: return .init(perviewImage: "edit_perview_textHookEdge".wmc_image)
            case .marked: return .init(perviewImage: "edit_perview_marked".wmc_image)
            case .tag: return .init(perviewImage: "edit_perview_tag".wmc_image)
            case .textBackground: return .init(perviewImage: "edit_perview_textBackground".wmc_image)
            }
        }
    }

    enum Colors: CaseIterable {
        case red
        case yellow
        case blue
        case green
        case purple
        case black
        case white

        struct Info {
            var hexStr: String
        }

        var info: Info {
            switch self {
            case .red: return .init(hexStr: "F54A45")
            case .yellow: return .init(hexStr: "F3BA35")
            case .blue: return .init(hexStr: "4197F5")
            case .green: return .init(hexStr: "4AB358")
            case .purple: return .init(hexStr: "514BE1")
            case .black: return .init(hexStr: "323232")
            case .white: return .init(hexStr: "FFFFFF")
            }
        }
    }
}

// MARK: - [WmcBaseTagView]

class WmcBaseTagView: WmcBaseView {
    // Internal

    /// 缩放手势
    lazy var pinchGesture: UIPinchGestureRecognizer = {
        let gesture = UIPinchGestureRecognizer.YP.Create { [weak self] pinch in
            guard let weakSelf = self else { return }
            weakSelf.handlePinchGesture(pinch)
        }
        gesture.delegate = self
        return gesture
    }()

    /// 旋转手势
    lazy var rotationGesture: UIRotationGestureRecognizer = {
        let gesture = UIRotationGestureRecognizer.YP.Create { [weak self] rotation in
            guard let weakSelf = self else { return }
            weakSelf.handleRotationGesture(rotation)
        }
        gesture.delegate = self
        return gesture
    }()

    /// 拖拽手势
    lazy var panGesture: UIPanGestureRecognizer = {
        let gesture = UIPanGestureRecognizer.YP.Create { [weak self] pan in
            guard let weakSelf = self else { return }
            weakSelf.handleMoveGesture(pan)
        }
        gesture.delegate = self
        return gesture
    }()

    /// 删除按钮
    lazy var deleteBtn: UIButton = {
        let btn = UIButton()
        btn.setImage("edit_tag_delete".wmc_image, for: .normal)
        btn.yp.addEvent { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.close()
        }
        return btn
    }()

    /// 缩放旋转图标
    lazy var scaleRotationImageView: UIImageView = {
        let imageView = UIImageView(image: "edit_tag_scale_rotation".wmc_image)
        imageView.contentMode = .scaleAspectFit
        return imageView
    }()

    /// 缩放旋转控制器
    lazy var scaleRotationControl: UIView = {
        let view = UIView()
        view.isUserInteractionEnabled = true
        view.tag = 100 // 100 以上的tag都需要特殊处理手势
        // 拖动手势，计算缩放和旋转
        let panGesture = UIPanGestureRecognizer.YP.Create { [weak self] pan in
            guard let weakSelf = self else { return }
            weakSelf.handleScaleRotateGesture(pan)
        }
        view.addGestureRecognizer(panGesture)
        return view
    }()

    /// 边框画布
    lazy var borderView: UIView = {
        let view = UIView()
        view.backgroundColor = .clear
        view.layer.borderWidth = 1
        view.layer.borderColor = UIColor.white.cgColor
        view.layer.masksToBounds = true
        return view
    }()

    /// 内容视图
    lazy var contentView: UIView = {
        let view = UIView()
        view.isUserInteractionEnabled = true
        return view
    }()

    /// 文字
    lazy var textLabel: UILabel = {
        let label = UILabel.YP.Create(text: defaultText,
                                      font: 19.wmc_autoVer.yp.uiFont(weight: .medium),
                                      color: UIColor.white,
                                      alignment: .left)
        label.numberOfLines = 0
        return label
    }()

    lazy var gestureView: UIView = {
        let view = UIView()
        view.isUserInteractionEnabled = true
        return view
    }()

    /// 边框边距
    var borderEdge: UIEdgeInsets = 14.yp.uiEdge
    /// 内容边距
    var contentEdge: UIEdgeInsets = 16.yp.uiEdge
    /// 默认大小
    var defaultSize: CGSize = .zero
    /// 最小缩放值
    var minScale: CGFloat = 0.5
    /// 手势结束回调
    var gestureEndBlock: YPBlock.OneParam<WmcBaseView>?
    /// 标签样式
    var tagStyle: TagStyle?
    /// 默认文字
    var defaultText: String = "请输入..."
    /// 当前的缩放值
    var currentScale: CGFloat = 1
    /// 当前的旋转角度
    var currentAngle: CGFloat = 0

    /// 颜色
    var color: Colors = .red { didSet { changeColor(color) } }
    /// 文字
    var text: String? {
        set {
            if (newValue?.count ?? 0) <= 0 {
                textLabel.text = defaultText
            } else {
                textLabel.text = newValue
            }
        }
        get { return textLabel.text }
    }

    /// 第一编辑者状态
    var isFirstEdit: Bool = false {
        didSet {
            borderView.isHidden = !isFirstEdit
            deleteBtn.isHidden = !isFirstEdit
            scaleRotationImageView.isHidden = !isFirstEdit
            scaleRotationControl.isHidden = !isFirstEdit
            gestureView.isHidden = !isFirstEdit
            if isFirstEdit { // 是编辑者状态
                // 移动到顶层
                superview?.bringSubviewToFront(self)
            }
        }
    }

    /// 关闭
    func close() {
        // 调整视图列表
        guard let preView = superview?.superview?.superview?.superview as? WmcEditPhotoPreviewView else { return }
        var newTagViews = preView.tagViews
        preView.tagViews.enumerated().forEach { (idx, tagView) in
            if tagView == self { // 找到自己，然后移除
                newTagViews = preView.tagViews.yp.remove(at: idx)
                return
            }
        }
        preView.tagViews = newTagViews
        removeFromSuperview()
    }

    /// 颜色发生变化
    func changeColor(_ color: Colors) {}

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let sView = super.hitTest(point, with: event)

        return sView
    }

    func copy() -> WmcBaseTagView {
        let new = Self()
        new.text = self.text
        new.color = self.color
        new.defaultSize = self.defaultSize
        return new
    }

    /// 移动手势
    func handleMoveGesture(_ recognizer: UIPanGestureRecognizer) {
        let touchLocation = recognizer.location(in: superview)
        switch recognizer.state {
        case .began:
            beginningPoint = touchLocation
            beginningCenter = center
            YPDevice.PlayShake(.light)
        case .changed:
            center = CGPoint(x: beginningCenter.x + (touchLocation.x - beginningPoint.x),
                             y: beginningCenter.y + (touchLocation.y - beginningPoint.y))
        case .ended:
            center = CGPoint(x: beginningCenter.x + (touchLocation.x - beginningPoint.x),
                             y: beginningCenter.y + (touchLocation.y - beginningPoint.y))
            moveFromImageViewToBack()
            YPDevice.PlayShake(.light)
        default: break
        }
    }

    /// 捏合缩放手势
    func handlePinchGesture(_ recognizer: UIPinchGestureRecognizer) {
        switch recognizer.state {
        case .changed:
            transform = transform.scaledBy(x: recognizer.scale, y: recognizer.scale)
        case .ended:
            recoreCurrentTransform()
            moveFromImageViewToBack()
            if currentScale < minScale {
                Wmc_SpringAnimation() { [weak self] in
                    guard let weakSelf = self else { return }
                    var rotationScaleTransform = CGAffineTransform(rotationAngle: weakSelf.currentAngle)
                    let minScale = weakSelf.minScale
                    rotationScaleTransform = rotationScaleTransform.scaledBy(x: minScale, y: minScale)
                    weakSelf.transform = rotationScaleTransform
                }
            }
        default: break
        }
        recognizer.scale = 1
    }

    /// 旋转手势
    func handleRotationGesture(_ recognizer: UIRotationGestureRecognizer) {
        switch recognizer.state {
        case .changed:
            transform = transform.rotated(by: recognizer.rotation)
            recognizer.rotation = 0 // 归零
        case .ended:
            recoreCurrentTransform()
            moveFromImageViewToBack()
        default: break
        }
    }

    /// 旋转缩放手势
    func handleScaleRotateGesture(_ recognizer: UIPanGestureRecognizer) {
        let touchLocation = recognizer.location(in: superview)
        let center = center

        switch recognizer.state {
        case .began:
            deltaAngle = CGFloat(atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))) - transform.yp.radian
            initialDistance = center.yp.distance(to: touchLocation)
        case .changed:
            let angle = atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))
            let angleDiff = Float(deltaAngle) - angle
            let scaleOffset = (center.yp.distance(to: touchLocation) / initialDistance)
            var scale = scaleOffset * currentScale
            if scale < minScale {
                scale = minScale
            }
            var rotationScaleTransform = CGAffineTransform(rotationAngle: CGFloat(-angleDiff))
            rotationScaleTransform = rotationScaleTransform.scaledBy(x: scale, y: scale)
            transform = rotationScaleTransform
            setNeedsDisplay()
        case .ended:
            recoreCurrentTransform()
            moveFromImageViewToBack()
        default: break
        }
    }

    /// 记录当前缩放
    func recoreCurrentTransform() {
        currentScale = transform.yp.scaleX
        currentAngle = transform.yp.radian
    }

    /// 标签移出后，自动返回屏幕中心
    func moveFromImageViewToBack() {
        gestureEndBlock?(self)
    }

    override func config() {
        isUserInteractionEnabled = true
        gestureView.addGestureRecognizer(panGesture)
        gestureView.addGestureRecognizer(pinchGesture)
        gestureView.addGestureRecognizer(rotationGesture)
    }

    override func makeUI() {
        backgroundColor = .clear

        addSubview(borderView)
        borderView.snp.makeConstraints { make in
            make.top.equalTo(borderEdge.top)
            make.left.equalTo(borderEdge.left)
            make.bottom.equalTo(-borderEdge.bottom)
            make.right.equalTo(-borderEdge.right)
        }

        addSubview(contentView)
        contentView.snp.makeConstraints { make in
            make.top.equalTo(borderView.snp.top).offset(contentEdge.top)
            make.left.equalTo(borderView.snp.left).offset(contentEdge.left)
            make.bottom.equalTo(borderView.snp.bottom).offset(-contentEdge.bottom)
            make.right.equalTo(borderView.snp.right).offset(-contentEdge.right)
        }

        addSubview(gestureView)
        gestureView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }

        addSubview(deleteBtn)
        deleteBtn.snp.makeConstraints { make in
            make.top.left.equalToSuperview()
            make.size.equalTo(28)
        }

        addSubview(scaleRotationImageView)
        scaleRotationImageView.snp.makeConstraints { make in
            make.right.bottom.equalToSuperview()
            make.size.equalTo(28)
        }

        addSubview(scaleRotationControl)
        scaleRotationControl.snp.makeConstraints { make in
            make.right.bottom.equalToSuperview()
            make.size.equalTo(35)
        }

        // 颜色初始化
        color = .red
    }

    /// 按钮等比缩放
    func controlSize(_ size: CGFloat) {
        deleteBtn.snp.updateConstraints { make in
            make.size.equalTo(size)
        }
        scaleRotationControl.snp.updateConstraints { make in
            make.size.equalTo(size)
        }
    }

    // Private

    private var initialDistance: CGFloat = 0
    private var deltaAngle: CGFloat = 0

    private var beginningPoint = CGPoint.zero
    private var beginningCenter = CGPoint.zero
}

// MARK: - UIGestureRecognizerDelegate

extension WmcBaseTagView: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let gestureView = otherGestureRecognizer.view else { return false }
        if let _ = gestureView as? UIScrollView {
            return false
        }
        if gestureView.tag >= 100 {
            return false
        }
        let mainGesture = gestureRecognizer == panGesture || gestureRecognizer == pinchGesture || gestureRecognizer == rotationGesture
        let otherGesture = otherGestureRecognizer == panGesture || otherGestureRecognizer == pinchGesture || otherGestureRecognizer == rotationGesture
        if mainGesture, otherGesture {
            return true
        }
        return false
    }
}
